package com.gzhryc.pay.adaptation.alipay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeCreateModel;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.config.PropertyTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.pay.models.IPayOrder;
import com.gzhryc.pay.models.IRefundOrder;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Properties;

/**
 * 支付宝扫码支付接口
 * 文档：当面付-扫码支付
 */
public class AlipayNormalPayService implements Serializable {

    private static final long serialVersionUID = 1L;

	static Logger log = Logger.getLogger(AlipayNormalPayService.class);

    DefaultAlipayConfig config;

    public AlipayNormalPayService(){}

    public AlipayNormalPayService(Properties properties) {
        this.config = PropertyTools.build(properties).getObject(DefaultAlipayConfig.class);
    }

    public AlipayNormalPayService(DefaultAlipayConfig config) {
        this.config = config;
    }

    public AlipayTradeCreateResponse applyPayOrder(IPayOrder payOrder) {
        AlipayTradeCreateResponse response = null;
        try {
            DefaultAlipayClient httpClient = AliHttpClient.getHttpClient(config);
            
         // 构造请求参数以调用接口
            AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
            AlipayTradeCreateModel model = new AlipayTradeCreateModel();
            
            // 设置商户订单号
            model.setOutTradeNo(payOrder.getTradeNo());
            
            // 设置订单总金额
            model.setTotalAmount(NumberTools.getMoneyStr(payOrder.getPayMoney()));
            
            // 设置订单标题
            model.setSubject(payOrder.getTitle());
            
            // 设置订单相对超时时间
            model.setTimeoutExpress("5m");
            
            // uid参数未来计划废弃，存量商户可继续使用，新商户请使用openid。请根据应用-开发配置-openid配置选择支持的字段。
            // model.setBuyerId("2088102146225135");
            
            // 设置买家支付宝用户唯一标识
            model.setBuyerOpenId(payOrder.getPayerId());
            
            // 设置产品码
            model.setProductCode("JSAPI_PAY");
            
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
            
            request.setNotifyUrl(this.config.getPayNotifyUrl());
            
            response = httpClient.execute(request);
            if (StringUtils.isNotBlank(config.getCertificatePath())) {
                response = httpClient.certificateExecute(request);
            } else {
                response = httpClient.execute(request);
            }
            return response;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public AlipayTradeRefundResponse applyRefundOrder(IRefundOrder refundOrder) {
        AlipayTradeRefundResponse response = null;
        //TODO 支付宝新版退款已不在支持回调
        try {
            DefaultAlipayClient httpClient = AliHttpClient.getHttpClient(config);
            // 设置请求参数
            AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
            Double money = NumberTools.changeMoney(refundOrder.getRefundMoney());
            alipayRequest.setBizContent("{\"out_trade_no\":\"" + refundOrder.getPayTradeNo() + "\"," + "\"trade_no\":\"" + "\"," + "\"refund_amount\":\"" + money
                    + "\"," + "\"refund_reason\":\"" + refundOrder.getNote() + "\"," + "\"out_request_no\":\"" + refundOrder.getTradeNo() + "\"}");
            if (StringUtils.isNotBlank(config.getCertificatePath())) {
                response = httpClient.certificateExecute(alipayRequest);
            } else {
                response = httpClient.execute(alipayRequest);
            }
            return response;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public AlipayTradeCloseResponse applyCloseOrder(String tradeNo) {
        AlipayTradeCloseResponse response = null;
        try {
            DefaultAlipayClient httpClient = AliHttpClient.getHttpClient(config);

            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", tradeNo);
            request.setBizContent(bizContent.toString());

            response = httpClient.execute(request);
            log.info("{{0}}支付宝订单关闭，响应信息：{{1:json}}", tradeNo, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return response;
    }

    public AlipayTradeQueryResponse queryByTradeNo(String tradeNo) {
        AlipayTradeQueryResponse response = null;
        try {
            DefaultAlipayClient httpClient = AliHttpClient.getHttpClient(config);

            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            request.setBizContent("{" + "\"out_trade_no\":\"" + tradeNo + "\"," + "\"trade_no\":\"\"," + "\"org_pid\":\"\","
                    + "\"query_options\":[" + "\"TRADE_SETTE_INFO\"" + "]" + "  }");
            if (StringUtils.isNotBlank(config.getCertificatePath())) {
                response = httpClient.certificateExecute(request);
            } else {
                response = httpClient.execute(request);
            }
            return response;
        } catch (AlipayApiException e) {
            log.error(e.getMessage(), e);
        } catch (LogicException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public AlipayTradeQueryResponse queryByExternalTradeNo(String externalTradeNo) {
        AlipayTradeQueryResponse response = null;
        try {
            DefaultAlipayClient httpClient = AliHttpClient.getHttpClient(config);

            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            request.setBizContent("{" + "\"out_trade_no\":\"\"," + "\"trade_no\":\"" + externalTradeNo + "\"," + "\"org_pid\":\"\","
                    + "\"query_options\":[" + "\"TRADE_SETTE_INFO\"" + "]" + "  }");
            if (StringUtils.isNotBlank(config.getCertificatePath())) {
                response = httpClient.certificateExecute(request);
            } else {
                response = httpClient.execute(request);
            }
            return response;
        } catch (AlipayApiException e) {
            log.error(e.getMessage(), e);
        } catch (LogicException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public AlipayTradeFastpayRefundQueryResponse queryRefundByTradeNo(String tradeNo) {
        AlipayTradeFastpayRefundQueryResponse response = null;
        try {
            DefaultAlipayClient httpClient = AliHttpClient.getHttpClient(config);

            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", tradeNo);
            bizContent.put("out_request_no", tradeNo);
            request.setBizContent(bizContent.toString());

            if (StringUtils.isNotBlank(config.getCertificatePath())) {
                response = httpClient.certificateExecute(request);
            } else {
                response = httpClient.execute(request);
            }
            return response;
        } catch (AlipayApiException e) {
            log.error(e.getMessage(), e);
        } catch (LogicException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public DefaultAlipayConfig getConfig(){
        return this.config;
    }
}
